﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
using XCI.Core;
using XCI.Helper;

namespace XCI.Service
{
    public class FileUploadService
    {
        private const string RootUrl = "/file";
        public static FileUploadService Instance { get; } = new FileUploadService();

        /// <summary>
        /// 创建上传文件完整Url
        /// </summary>
        /// <param name="url">url路径</param>
        public string BuildUploadFullUrl(string url)
        {
            if (string.IsNullOrEmpty(url)) throw new ArgumentNullException(nameof(url));
            string startVar = string.Empty;
            if (!url.StartsWith("/"))
            {
                startVar = "/";
            }
            var config = App.Setting.FileServer != null ? App.Setting.FileServer : App.Setting.Server;
            return $"{config.BaseUrl}{config.UploadRootUrl}{startVar}{url}";
        }

        /// <summary>
        /// 上传文件
        /// </summary>
        /// <param name="localFilePath">待上传的本地文件路径</param>
        /// <param name="virtualCatalog">文件虚拟目录(选填)</param>
        public async Task<FileModel> UploadAsync(string localFilePath, string virtualCatalog = null)
        {
            return await App.FileClient.UploadAsync<FileModel>($"{RootUrl}/upload", localFilePath, new { virtualCatalog });
        }

        /// <summary>
        /// 下载文件
        /// </summary>
        /// <param name="remoteFilePath">远程文件路径</param>
        /// <param name="localFilePath">文件本地存储路径</param>
        /// <param name="md5">文件md5,可为null</param>
        public Task DownloadAsync(string remoteFilePath, string localFilePath, string md5 = null)
        {
            return App.FileClient.DownloadAsync($"{RootUrl}/download", localFilePath, new { virtualFilePath = remoteFilePath, md5 });
        }

        /// <summary>
        /// 下载文件
        /// </summary>
        /// <param name="remoteFilePath">远程文件路径</param>
        /// <param name="md5">文件md5,可为null</param>
        public async Task<byte[]> DownloadAsBytesAsync(string remoteFilePath, string md5 = null)
        {
            string tempFile = Path.GetTempFileName();
            await DownloadAsync(remoteFilePath, tempFile, md5);
            var result = File.Exists(tempFile) ? IOHelper.ReadFile(tempFile) : null;
            IOHelper.DeleteFile(tempFile);
            return result;
        }

        /// <summary>
        /// 删除文件
        /// </summary>
        /// <param name="remoteFilePath">远程文件路径</param>
        public Task DeleteAsync(string remoteFilePath)
        {
            return App.FileClient.PostAsync($"{RootUrl}/delete", new { virtualFilePath = remoteFilePath });
        }

        /// <summary>
        /// 删除文件,返回BoolResult
        /// </summary>
        /// <param name="remoteFilePath">远程文件路径</param>
        public async Task<BoolResult> DeleteAsResultAsync(string remoteFilePath)
        {
            var result = await App.FileClient.PostAsBoolResultAsync($"{RootUrl}/delete", new { virtualFilePath = remoteFilePath });
            return result;
        }

        /// <summary>
        /// 复制文件
        /// </summary>
        /// <param name="srcRemoteFilePath">源文件路径</param>
        /// <param name="destRemoteFilePath">目标文件路径</param>
        public Task CopyAsync(string srcRemoteFilePath, string destRemoteFilePath)
        {
            return App.FileClient.PostAsync($"{RootUrl}/copy", new { srcVirtualFilePath = srcRemoteFilePath, destVirtualFilePath = destRemoteFilePath });
        }

        /// <summary>
        /// 检查文件是否存在
        /// </summary>
        /// <param name="remoteFilePath">检查的远程文件路径</param>
        public Task<bool> ExistsAsync(string remoteFilePath)
        {
            return App.FileClient.PostAsync<bool>($"{RootUrl}/exists", new { virtualFilePath = remoteFilePath });
        }

        /// <summary>
        /// 查询文件列表
        /// </summary>
        /// <param name="virtualCatalog">文件虚拟目录</param>
        public async Task<List<FileModel>> ListAsync(string virtualCatalog)
        {
            return await App.FileClient.PostAsync<List<FileModel>>($"{RootUrl}/list", new { virtualCatalog });
        }

        /// <summary>
        /// 查询目录下文件数量(不含子目录)
        /// </summary>
        /// <param name="virtualCatalog">文件虚拟目录</param>
        public async Task<long> CountAsync(string virtualCatalog)
        {
            return await App.FileClient.PostAsync<long>($"{RootUrl}/count", new { virtualCatalog });
        }

        /// <summary>
        /// 获取文件信息
        /// </summary>
        /// <param name="virtualFilePaths">虚拟文件路径字符串,多个路径间用逗号隔开</param>
        public async Task<FileModel> InfoAsync(string virtualFilePaths)
        {
            return await App.FileClient.PostAsync<FileModel>($"{RootUrl}/info", new { virtualFilePaths });
        }

    }
}